import threading
import queue
import wave

import pyaudio

import time

CHUNK = 1024  # wav文件是由若干个CHUNK组成的，CHUNK我们就理解成数据包或者数据片段。
FORMAT = pyaudio.paInt16  # 表示我们使用量化位数 16位来进行录音
CHANNELS = 2  # 代表的是声道，1是单声道，2是双声道。
RATE = 44100  # 采样率 一秒内对声音信号的采集次数，常用的有8kHz, 16kHz, 32kHz, 48kHz,
# 11.025kHz, 22.05kHz, 44.1kHz。
RECORD_SECONDS = 5

exe_obj = None

class Audio_except():
    flag_dict = {}
    queue_dict = {}
    stream_dict = {}

    def __init__(self):
        self.p = pyaudio.PyAudio()
        self.pyaudio_open(2, 'ch12')

    @staticmethod
    def audio_a_obj():
        global exe_obj
        if not exe_obj:
            exe_obj = Audio_except()
        return exe_obj

    def change_key(self, index, chanle):
        return str(index) + '_' + str(chanle)

    def pyaudio_open(self, index, chanle):
        k = self.change_key(index, chanle)
        self.stream_dict[k] = self.p.open(format=FORMAT,
                                          channels=CHANNELS,
                                          rate=RATE,
                                          input=True,
                                          frames_per_buffer=CHUNK)

    def put_in_queue(self, index, chanle):
        thd = threading.current_thread()
        print('start put_in_queue', thd)
        k = self.change_key(index, chanle)
        self.flag_dict[k] = True
        self.queue_dict[k] = queue.Queue()
        while True:
            flag = self.flag_dict[k]
            if flag:
                data = self.stream_dict[k].read(CHUNK)
                # self.queue_dict[k].put_nowait('22')
                self.queue_dict[k].put(data)
            else:
                print('end put_in_queue', thd)
                break

    def get_out_queue(self, index, chanle):
        thd = threading.current_thread()
        print('start get_out_queue', thd)
        k = self.change_key(index, chanle)
        wf = wave.open('test.wav', 'wb')
        wf.setnchannels(CHANNELS)
        wf.setsampwidth(self.p.get_sample_size(FORMAT))
        wf.setframerate(RATE)
        while True:
            flag = self.flag_dict[k]
            if flag:
                # data = self.queue_dict[k].get_nowait()
                data = self.queue_dict[k].get()
                wf.writeframes(data)
                # print('got a data: ',data)
            else:
                wf.close()
                print('end get_out_queue', thd)
                break

    def start_queue(self, index, chanle):
        t1 = threading.Thread(target=self.put_in_queue, args=(index, chanle))
        t2 = threading.Thread(target=self.get_out_queue, args=(index, chanle))
        t1.setDaemon(False)
        t1.start()
        t2.setDaemon(False)
        t2.start()


    def stop_queue(self, index, chanle):
        print('flag_dict',self.flag_dict)
        print('queue_dict',self.queue_dict)
        print('stream_dict',self.stream_dict)
        thd = threading.current_thread()
        print('start stop_queue', thd)
        k = self.change_key(index, chanle)
        self.flag_dict[k] = False
        print('flag_dict', self.flag_dict)
        self.queue_dict[k].queue.clear()
        print('end stop_queue', thd)

    def main(self):
        thd = threading.current_thread()
        print('start main', thd)
        self.start_queue(2, 'ch12')
        time.sleep(5)
        self.stop_queue(2, 'ch12')
        print('end main', thd)

    def test_thd(self):
        thd = threading.current_thread()
        print('start test_thd', thd)
        t = threading.Thread(target=self.main)
        t.start()
        print('start test_thd', thd)


if __name__ == '__main__':
    audio_obj = Audio_except()
    audio_obj.test_thd()
    p = pyaudio.PyAudio()
    count = p.get_device_count()
    for i in range(count):
        cc = p.get_device_info_by_index(i)
        print(cc)
    print(count)
